// 对epoll进行封装
#pragma once

#include <iostream>
#include <sys/epoll.h>
#include "Common.hpp"

//简单的封装一下IO控制的模型。
namespace EpollModule
{
    class Epoller
    {
    public:
        Epoller() : _epfd(-1)
        {
        }
        void Init()
        {
            _epfd = ::epoll_create(200);
            if (_epfd < 0)
            {
                std::cout << "epoll_create error" << std::endl;
                exit(EPOLL_CREATE_ERR);
            }
            std::cout << "epoll_create success: " << _epfd << std::endl;
        }
        int Wait(struct epoll_event revs[], int num, int timeout) // 用这两个参数输入就绪的fd和events
        {
            // int n = epoll_wait(_epfd,revs,num,-1);//默认阻塞了timeout=-1
            int n = epoll_wait(_epfd, revs, num, timeout); // 交给外部做处理，外部决定阻塞逻辑，这样也实现了，功能的拓展，我是ET还是LT模型，就是实现了其中一步了。
            if (n < 0)
            {
                std::cout << "epoll_wait error" << std::endl;
            }
            return n;
        }
        void Ctrl(int sockfd, uint32_t events, int flag)
        {
            struct epoll_event ev;
            ev.data.fd = sockfd;
            ev.events = events;
            int n = epoll_ctl(_epfd, flag, sockfd, &ev);
            if (n < 0)
            {
                std::cout << "epoll_ctl error" << std::endl;
            }
            std::cout << "epoll_ctl succuss" << std::endl;
        }
        void Add(int sockfd, uint32_t events)
        {
            Ctrl(sockfd, events, EPOLL_CTL_ADD);
        }
        void Updata(int sockfd, uint32_t events)
        {
            Ctrl(sockfd, events, EPOLL_CTL_MOD);
        }
        //vesion-1删除你关心的事件
        // void Delete(int sockfd, uint32_t events)
        // {
        //     Ctrl(sockfd, events, EPOLL_CTL_DEL);
        // }
        //vesion-2不管什么事件直接把fd从Epoll中移除
        void Delete(int sockfd)
        { 
            int n = epoll_ctl(_epfd,EPOLL_CTL_DEL, sockfd, nullptr);
            if (n < 0)
            {
                std::cout << "epoll_ctl error" << std::endl;
            }
            std::cout << "epoll_ctl succuss" << std::endl;
        }
        ~Epoller() {}

    private:
        int _epfd;
    };
}